"""
Case Type   : GUC_ErrorLog
Case Name   : 参数log_truncate_on_rotation的值为on,覆盖写入的方式写服务器日志消息
Create At   : 2022/06/02
Owner       : liu-tong-8848
Description :
    1.logging_collector设置为on,log_directory设置新的路径，将日志存储到数据目录之外的地方
    2.参数log_truncate_on_rotation的值设置为on,重新设置log_filename
    3.重启数据库，生成相关日志文件
    4.修改当前时间为一周后的今天，再次重启数据库，查看生成的相关日志内容
    5.恢复参数
    6.恢复系统时间
    7.清理残留日志
Expect      :
    1.设置成功
    2.设置成功
    3.重启成功，生成相关日志文件成功
    4.修改时间成功，重启成功，生成相关日志文件成功
    5.恢复成功
    6.恢复成功
    7.清理成功
History     :
"""
import os
import unittest
from yat.test import Node
from yat.test import macro
from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Logger import Logger
from testcase.utils.Constant import Constant


class ErrorLog(unittest.TestCase):
    def setUp(self):
        self.logger = Logger()
        self.logger.info(f"-----{os.path.basename(__file__)} start-----")
        self.primary_node = Node('PrimaryDbUser')
        self.primary_sh = CommonSH('PrimaryDbUser')
        self.primary_root = Node('PrimaryRoot')
        self.common = Common()
        self.constant = Constant()
        self.dir_new = os.path.join(macro.PG_LOG_PATH, 'pg_errorlog_case0026')
        self.new_filename = 'server_log_0026.%a'
        self.logfile = ''
        self.collector = 'logging_collector'
        self.collector_default = self.common.show_param(self.collector)
        self.log_dir = 'log_directory'
        self.log_dir_default = self.common.show_param(self.log_dir)
        self.log_trunc = 'log_truncate_on_rotation'
        self.log_trunc_default = self.common.show_param(self.log_trunc)
        self.log_filename = 'log_filename'
        self.log_filename_default = self.common.show_param(self.log_filename)
        self.query_date_cmd = 'date "+%Y-%m-%d %H:%M:%S"'

    def test_error_log(self):
        text = '-----step1:logging_collector设置为on,log_directory设置新的路径，' \
               '将日志存储到数据目录之外的地方;expect:设置成功-----'
        self.logger.info(text)
        if 'on' != self.collector_default:
            result = self.primary_sh.execute_gsguc(
                'set', self.constant.GSGUC_SUCCESS_MSG,
                f'{self.collector}=on')
            self.assertTrue(result, '执行失败' + text)
            restart_res = self.primary_sh.restart_db_cluster()
            self.assertTrue(restart_res, '执行失败' + text)
        show_msg = self.common.show_param(self.collector)
        self.assertEquals(show_msg, 'on', '执行失败' + text)
        if self.dir_new != self.log_dir_default:
            result = self.primary_sh.execute_gsguc(
                'reload', self.constant.GSGUC_SUCCESS_MSG,
                f'{self.log_dir}=\'{self.dir_new}\'')
            self.assertTrue(result, '执行失败' + text)
        show_msg = self.common.show_param(self.log_dir)
        self.assertEquals(show_msg, self.dir_new, '执行失败' + text)

        text = '-----step2:参数log_truncate_on_rotation的值设置为on,' \
               '重新设置log_filename;expect:设置成功-----'
        self.logger.info(text)
        if 'on' != self.log_trunc_default:
            result = self.primary_sh.execute_gsguc(
                'reload', self.constant.GSGUC_SUCCESS_MSG,
                f'{self.log_trunc}=on')
            self.assertTrue(result, '执行失败' + text)
        show_msg = self.common.show_param(self.log_trunc)
        self.assertEquals(show_msg, 'on', '执行失败' + text)
        if self.new_filename != self.log_filename_default:
            result = self.primary_sh.execute_gsguc(
                'reload', self.constant.GSGUC_SUCCESS_MSG,
                f'{self.log_filename}=\'{self.new_filename}\'')
            self.assertTrue(result, '执行失败' + text)
        show_msg = self.common.show_param(self.log_filename)
        self.assertEquals(show_msg, self.new_filename, '执行失败' + text)

        text = '-----step3:重启数据库，生成相关日志文件;' \
               'expect:重启成功，生成相关日志文件成功-----'
        self.logger.info(text)
        restart_res = self.primary_sh.restart_db_cluster()
        self.assertTrue(restart_res, '执行失败' + text)
        find_file_cmd = f'find {self.dir_new} -name server_log_0026*'
        self.logger.info(find_file_cmd)
        find_result = self.primary_node.sh(find_file_cmd).result()
        self.logger.info(find_result)
        self.logfile = find_result.strip()
        self.logger.info('-------查看日志文件内容-------')
        current_date = self.primary_root.sh(self.query_date_cmd).result()
        self.logger.info(current_date)
        cat_cmd = f'cat {self.logfile} '
        self.logger.info(cat_cmd)
        cat_msg = self.primary_node.sh(cat_cmd).result()
        self.logger.info(cat_msg)
        self.assertIn(current_date[:10] and 'LOG:  database system is shut down'
                      and 'database first startup and recovery finish',
                      cat_msg, '执行失败' + text)

        text = '-----step4:修改当前时间为一周后的今天，再次重启数据库，查看生成' \
               '的相关日志内容;expect:修改时间成功，重启成功，生成相关日志文件成功-----'
        self.logger.info(text)
        self.logger.info("----修改系统时间----")
        sql_cmd = f"select date '{current_date}' + interval '7 days' as result;"
        sql_msg = self.primary_sh.execut_db_sql(sql_cmd)
        self.logger.info(sql_msg)
        date_later = sql_msg.splitlines()[-2].strip()
        self.logger.info(date_later)
        set_date_cmd = f'date -s "{date_later}"'
        self.logger.info(set_date_cmd)
        result = self.primary_root.sh(set_date_cmd).result()
        self.logger.info(result)
        set_res = self.primary_root.sh(self.query_date_cmd).result()
        self.logger.info(set_res)
        self.assertEquals(set_res[:10], date_later[:10], '修改系统时间失败')
        self.logger.info('-------重启数据库生成日志文件-------')
        restart_res = self.primary_sh.restart_db_cluster()
        self.assertTrue(restart_res, '重启失败')
        self.logger.info('-------查看生成的相关日志内容-------')
        cat_cmd = f'cat {self.logfile} '
        self.logger.info(cat_cmd)
        cat_msg = self.primary_node.sh(cat_cmd).result()
        self.logger.info(cat_msg)
        self.assertIn(date_later[:10] and 'LOG:  database system is shut down'
                      and 'database first startup and recovery finish',
                      cat_msg, '执行失败' + text)
        self.assertNotIn(current_date[:10], cat_msg, '执行失败' + text)

    def tearDown(self):
        text_1 = '-----step5:恢复参数;expect:恢复成功-----'
        self.logger.info(text_1)
        log_trunc_current = self.common.show_param(self.log_trunc)
        if self.log_trunc_default != log_trunc_current:
            self.guc_result = self.primary_sh.execute_gsguc(
                'reload', self.constant.GSGUC_SUCCESS_MSG,
                f'{self.log_trunc}={self.log_trunc_default}')
        show_log_trunc = self.common.show_param(self.log_trunc)
        log_filename_current = self.common.show_param(self.log_filename)
        if self.log_filename_default != log_filename_current:
            self.primary_sh.execute_gsguc(
                'reload', self.constant.GSGUC_SUCCESS_MSG,
                f'{self.log_filename}=\'{self.log_filename_default}\'')
        show_log_filename = self.common.show_param(self.log_filename)
        collector_current = self.common.show_param(self.collector)
        if collector_current != self.collector_default:
            result = self.primary_sh.execute_gsguc(
                'set', self.constant.GSGUC_SUCCESS_MSG,
                f'{self.collector}={self.collector_default}')
            self.logger.info(result)
            restart_res = self.primary_sh.restart_db_cluster()
            self.logger.info(restart_res)
        show_collector = self.common.show_param(self.collector)
        log_dir_current = self.common.show_param(self.log_dir)
        if log_dir_current != self.log_dir_default:
            result = self.primary_sh.execute_gsguc(
                'reload', self.constant.GSGUC_SUCCESS_MSG,
                f'{self.log_dir}=\'{self.log_dir_default}\'')
            self.logger.info(result)
        show_log_dir = self.common.show_param(self.log_dir)

        text_2 = '-----step6:恢复系统时间;expect:恢复成功-----'
        self.logger.info(text_2)
        current = self.primary_root.sh(self.query_date_cmd).result()
        self.logger.info(current)
        sql_cmd = f"select date '{current}' - interval '7 days' as result;"
        sql_msg = self.primary_sh.execut_db_sql(sql_cmd)
        self.logger.info(sql_msg)
        date_before = sql_msg.splitlines()[-2].strip()
        set_date_cmd = f'date -s "{date_before}"'
        self.logger.info(set_date_cmd)
        result = self.primary_root.sh(set_date_cmd).result()
        self.logger.info(result)
        set_res = self.primary_root.sh(self.query_date_cmd).result()
        self.logger.info(set_res)

        text_remove = '-----step7:清理残留日志文件;expect:清理成功-----'
        remove_cmd = f"rm -rf {self.dir_new}"
        remove_result = self.primary_node.sh(remove_cmd).result()
        self.logger.info(remove_result)
        remove_test_cmd = f"ls {self.dir_new}"
        remove_test_log = self.primary_node.sh(remove_test_cmd).result()
        self.logger.info(remove_test_log)

        self.logger.info('-----断言tearDown-----')
        self.assertEquals(show_log_trunc, self.log_trunc_default,
                          '执行失败' + text_1)
        self.assertEquals(show_log_filename, self.log_filename_default,
                          '执行失败' + text_1)
        self.assertEquals(show_collector, self.collector_default,
                          '执行失败' + text_1)
        self.assertEquals(show_log_dir, self.log_dir_default, '执行失败' + text_1)
        self.assertEquals(set_res[:10], date_before[:10], '执行失败' + text_2)
        self.assertIn("No such file or directory", remove_test_log, '执行失败:' + text_remove)
        self.logger.info(f"-----{os.path.basename(__file__)} end-----")
